Imports IICBusinessLogic
Imports IICBusinessLogic.PeriodProcessing

''' <summary>
''' Test that sets up earing diploma in 2 periods.
''' 
''' </summary>
Public Class MultiplePeriodTest

    ''' <summary>Processor of first period in test</summary>
    Private _firstPeriodProcess As PeriodProcessor

    ''' <summary>Processor of second period in test</summary>
    Private _secondPeriodProcess As PeriodProcessor

    Public ReadOnly Property FirstPeriodProcessor() As PeriodProcessor
        Get
            Return _firstPeriodProcess
        End Get
    End Property

    Public ReadOnly Property SecondPeriodProcessor() As PeriodProcessor
        Get
            Return _secondPeriodProcess
        End Get
    End Property

    Sub setupMultiplePeriodTest()

        Dim studentManager As IStudentClassManager = New StudentClassManagerFactory().getStudentClassManager
        Dim maxPeriodDate As Date = _
            ModelContext.CurrentDBUtils.getDtValue("select max(periodDate) from [Period]")
        Dim expectedNumberProcessed As Integer = 0
        Dim numberOfLessons As Integer = 7

        Dim pdb As PeriodDBMapper = New PeriodDBMapper
        Dim diploma As DiplomaType = PeriodProcessorTestUtils.createDiplomaWithXCertReq(4)

        Dim lessons As List(Of Lesson) = New List(Of Lesson)
        Dim students As List(Of Student) = New List(Of Student)

        Dim ldb As New LessonDBMapper()
        For i As Integer = 1 To numberOfLessons
            lessons.Add(PeriodProcessorTestUtils.CreateLesson(100, 70))
        Next

        LessonDataUtils.saveLesson(lessons.ToArray)

        '***** 7 lessons: 1,2,3 is common requirement
        For Each dr As DiplomaRequirement In diploma.DiplomaRequirements
            For i As Integer = 0 To 2
                dr.Certification.AddLessonRequirement(lessons(i))
            Next
        Next
        '-----Lessons 4,5,6,7 each certificate.
        diploma.DiplomaRequirements(0).Certification.AddLessonRequirement(lessons(3))
        diploma.DiplomaRequirements(1).Certification.AddLessonRequirement(lessons(4))
        diploma.DiplomaRequirements(2).Certification.AddLessonRequirement(lessons(5))
        diploma.DiplomaRequirements(3).Certification.AddLessonRequirement(lessons(6))
        DiplomaTypeDataUtils.saveDiplomaType(diploma)


        For st As Integer = 0 To 3
            Dim cnt As Integer = PeriodProcessorTestUtils.getNextStudentCounter
            Dim stud As Student = StudentFactory.Create
            stud.FirstName = "t58 " & cnt
            stud.LastName = "fname"
            stud.IdNumber = "t58" & cnt
            students.Add(stud)
        Next

        Dim studeException As StudentLessonCredit = StudentLessonCreditFactory.Create
        studeException.LessonId = lessons(0).LessonId
        studeException.EffectiveDate = DateAdd(DateInterval.Month, 1, maxPeriodDate)

        students(2).AddStudentLessonCredit(studeException)

        StudentDataUtils.saveStudent(students.ToArray)

        'create a Period of classes
        Dim period As Period = PeriodFactory.Create
        period.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId
        period.PeriodDate = DateAdd(DateInterval.Month, 1, maxPeriodDate)
        period.PeriodCode = "58" & ModelContext.CurrentDBUtils.getIntValue("select count(*)+1 from period")
        Dim pername As String = period.PeriodName
        pdb.save(period)

        For Each ls As Lesson In lessons
            Dim pclass As PeriodClass = PeriodClassFactory.Create
            pclass.LessonId = ls.LessonId
            pclass.ExamCenterID = 2
            pclass.PassGrade = ls.DefaultPassGrade
            pclass.MaxGrade = ls.DefaultMaxGrade
            period.AddClass(pclass)

            Dim scnt As Integer = 0
            For Each s As Student In students
                scnt = scnt + 1
                Dim cm As ClassMember = studentManager.addStudentToClass(s, pclass)
                cm.StudentId = s.StudentId
                cm.Attend = True
                cm.Grade = CInt(IIf(scnt = 1, pclass.PassGrade + 1, pclass.PassGrade - 1))
                'only first student passes all
                pclass.AddMember(cm)
                expectedNumberProcessed = expectedNumberProcessed + 1
            Next

        Next

        pdb.save(period)
        Dim perid As Integer = period.PeriodId
        'now we see if student1 above has earned the diploma as expected
        _firstPeriodProcess = New PeriodProcessor(period)
        _firstPeriodProcess.processPeriodAndStoreToDatabase()
        'after processing, the studeException should not exist in ExceptionSatisfiedRequirement
        'todo: recheck this assertion after redesign of diploma.cerrts earned
        'Assert.IsTrue(ExceptionSatisfiedRequirementDataUtils.findOne("StudentLessonExceptionId={0}", studeException.StudentLessonExceptionId) Is Nothing, "Not expecting exception in ExceptionSatisfiedRequirementData")

        period = Nothing
        period = PeriodDataUtils.findByKey(perid)
        Assert.AreEqual(expectedNumberProcessed, _firstPeriodProcess.ExamsStudentProcessor.classMembersProcessed.Count)
        Dim pcs As List(Of PeriodClass) = period.Classes.ToList
        For Each pc As PeriodClass In pcs
            Dim mlst As List(Of ClassMember) = pc.Members.ToList
            For Each m As ClassMember In mlst
                Assert.AreEqual(_firstPeriodProcess.PeriodProcess.PeriodProcessId, _
                                m.PeriodProcessId)
            Next
        Next

        Assert.AreEqual(1, _firstPeriodProcess.diplomasEarned.Count)
        'setup second period
        period = PeriodFactory.Create
        period.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId
        period.PeriodDate = DateAdd(DateInterval.Month, 2, maxPeriodDate)
        period.PeriodCode = "58.2" & ModelContext.CurrentDBUtils.getIntValue("select count(*)+1 from period")

        pdb.save(period)

        'create a class with Student(2) and pass all 
        'lessons except lesson(0) (that is why we start from 1)
        For i As Integer = 1 To lessons.Count - 1
            Dim ls As Lesson = lessons(i)
            Dim pclass As PeriodClass = PeriodClassFactory.Create
            pclass.LessonId = ls.LessonId
            pclass.ExamCenterID = 2
            pclass.MaxGrade = ls.DefaultMaxGrade
            pclass.PassGrade = ls.DefaultPassGrade
            period.AddClass(pclass)
            Dim scnt As Integer = 0
            Dim cm As ClassMember = studentManager.addStudentToClass(students(2), pclass)

            cm.Attend = True
            cm.Grade = pclass.PassGrade + 1
            'only first student passes all
            pclass.AddMember(cm)

        Next
        pdb.save(period)

        'now we see if student1 above has earned the diploma as expected
        _secondPeriodProcess = New PeriodProcessor(period)
        _secondPeriodProcess.processPeriodAndStoreToDatabase()
        Assert.AreEqual(1, _secondPeriodProcess.diplomasEarned.Count)

    End Sub
End Class
